package cn.yh.register.user.service.impl;

import java.util.Date;

import cn.yh.register.common.util.JwtHelper;
import cn.yh.register.enums.AuthStatusEnum;
import cn.yh.register.model.user.Patient;
import cn.yh.register.model.user.UserLoginRecord;
import cn.yh.register.user.mapper.UserLoginRecordMapper;
import cn.yh.register.user.service.PatientService;
import cn.yh.register.vo.user.UserAuthVo;
import cn.yh.register.vo.user.UserInfoQueryVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;

import cn.yh.register.common.exception.RegisterException;
import cn.yh.register.common.result.ResultCodeEnum;
import cn.yh.register.model.user.UserInfo;
import cn.yh.register.user.mapper.UserInfoMapper;
import cn.yh.register.user.service.UserInfoservice;
import cn.yh.register.vo.user.LoginVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoservice {
    @Autowired
    UserLoginRecordMapper userLoginRecordMapper;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    PatientService patientService;

    /**
     * 登录
     *
     * @param loginVo 登录信息
     * @return Map<String, Object>
     */
    @Override
    public Map<String, Object> login(LoginVo loginVo) {
        String phone = loginVo.getPhone();
        String code = loginVo.getCode();

        // 参数非空校验
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
            throw new RegisterException(ResultCodeEnum.PARAM_ERROR);
        }
        // 验证码校验
        //校验校验验证码
        if (!code.equals(redisTemplate.opsForValue().get(phone))) {
            throw new RegisterException(ResultCodeEnum.CODE_ERROR);
        }
        //判断手机号是否已存在
        UserInfo userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getPhone, phone));
        if (userInfo == null) {
            //如果不存在，则注册用户
            userInfo = new UserInfo();
            userInfo.setPhone(phone);
            userInfo.setAuthStatus(0); //0：未认证 1：认证中 2：认证成功 -1：认证失败
            userInfo.setStatus(1);  //0：锁定 1：正常
            baseMapper.insert(userInfo);
        }
        //判断校验
        if (userInfo.getStatus() == 0) {
            throw new RegisterException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
        }
        userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getPhone, userInfo.getPhone()));

        // 保存登录记录
        UserLoginRecord record = new UserLoginRecord();
        record.setUserId(userInfo.getId());
        record.setIp(loginVo.getIp());
        userLoginRecordMapper.insert(record);


        String name = userInfo.getName();

        // 登录成功，将信息存入 map返回
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isEmpty(name)) {
            name = userInfo.getNickName();
        }
        if (StringUtils.isEmpty(name)) {
            name = userInfo.getPhone();
        }
        String token = JwtHelper.createToken(userInfo.getId(), name);
        map.put("name", name);
        map.put("token", token);
        return map;
    }

    /**
     * 用户认证
     *
     * @param userId     用户id
     * @param userAuthVo 认证信息
     */
    @Override
    public void userAuth(Long userId, UserAuthVo userAuthVo) {
        UserInfo userInfo = baseMapper.selectById(userId);
        if (userInfo != null) {
            BeanUtils.copyProperties(userAuthVo, userInfo);
            userInfo.setAuthStatus(1); // 1：认证中

            baseMapper.updateById(userInfo);
        }
    }

    /**
     * 获取用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    @Override
    public UserInfo getUserInfo(Long userId) {
        UserInfo userInfo = baseMapper.selectById(userId);
        if (userInfo != null) {
            this.packUserInfo(userInfo);
            return userInfo;
        }

        return null;
    }

    /**
     * 分页查询用户列表
     *
     * @param current 当前页码
     * @param limit   每页条数
     * @param queryVo 查询条件
     * @return 数据
     */
    @Override
    public Page<UserInfo> findUserList(Integer current, Integer limit, UserInfoQueryVo queryVo) {
        Page<UserInfo> page = new Page<>(current, limit);
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        // 用户名
        wrapper.like(!StringUtils.isEmpty(queryVo.getKeyword()), UserInfo::getName, queryVo.getKeyword())
                .or()
                //手机号
                .like(!StringUtils.isEmpty(queryVo.getKeyword()), UserInfo::getPhone, queryVo.getKeyword())
                //状态
                .eq(!StringUtils.isEmpty(queryVo.getStatus()), UserInfo::getStatus, queryVo.getStatus())
                //认证状态
                .eq(!StringUtils.isEmpty(queryVo.getAuthStatus()), UserInfo::getAuthStatus, queryVo.getAuthStatus())
                //创建时间
                .ge(!StringUtils.isEmpty(queryVo.getCreateTimeBegin()), UserInfo::getCreateTime, queryVo.getCreateTimeBegin())
                .le(!StringUtils.isEmpty(queryVo.getCreateTimeEnd()), UserInfo::getCreateTime, queryVo.getCreateTimeEnd());

        Page<UserInfo> userInfoPage = baseMapper.selectPage(page, wrapper);
        userInfoPage.getRecords().forEach(this::packUserInfo);
        return userInfoPage;
    }

    /**
     * 用户锁定
     *
     * @param userId 用户id
     * @param status 状态
     */
    @Override
    public void lock(Long userId, Integer status) {
        if (status.intValue() == 0 || status.intValue() == 1) {
            UserInfo userInfo = getUserInfo(userId);
            userInfo.setStatus(status);
            baseMapper.updateById(userInfo);
        }
    }

    /**
     * 查看用户详情
     *
     * @param userId 用户id
     * @return Map<String, Object>
     */
    @Override
    public Map<String, Object> show(Long userId) {
        Map<String, Object> map = new HashMap<>();
        //用户信息
        UserInfo userInfo = this.getUserInfo(userId);
        if (userInfo != null) {
            //就诊人信息
            List<Patient> patientList = patientService.findUserById(userId);
            map.put("userInfo", userInfo);
            map.put("patientList", patientList);
        }
        return map;
    }

    /**
     * 认证审批
     *
     * @param userId     用户id
     * @param authStatus 用户状态
     */
    @Override
    public void approval(Long userId, Integer authStatus) {
        UserInfo userInfo = baseMapper.selectById(userId);
        if (userInfo != null) {
            if (authStatus.intValue() == 2 || authStatus.intValue() == -1) {
                userInfo.setAuthStatus(authStatus);
                baseMapper.updateById(userInfo);
            }
        }
    }

    private void packUserInfo(UserInfo userInfo) {

        //认证状态
        String authStatusString = AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus());
        //状态
        String statusString = userInfo.getStatus() == 0 ? "锁定" : "正常";
        //证件类型
        if (!StringUtils.isEmpty(userInfo.getCertificatesType())) {
            String certificatesTypeString = userInfo.getCertificatesType().equals("10") ? "身份证" : "户口本";

            userInfo.getParam().put("certificatesTypeString", certificatesTypeString);
        }
        userInfo.getParam().put("authStatusString", authStatusString);
        userInfo.getParam().put("statusString", statusString);
    }
}
